﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Abp.Auditing;
using Abp.Authorization;
using Abp.Extensions;
using Abp.IO.Extensions;
using Abp.MimeTypes;
using Abp.UI;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using pandx.Mulan.Authorization;
using pandx.Mulan.Dto;
using pandx.Mulan.Folders;
using pandx.Mulan.Helpers;
using pandx.Mulan.Storage;

namespace pandx.Mulan.Controllers
{
    public class FileControllerBase : MulanControllerBase
    {
        private const long MaxCommonFileSize = 1024 * 1024 * 10;
        private readonly ITempFileCacheManager _tempFileCacheManager;
        private readonly IBinaryObjectManager _binaryObjectManager;
        private readonly IMimeTypeMap _mimeTypeMap;
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly FileUploadHelper _fileUploadHelper;
        private readonly IAppFolder _appFolder;

        public FileControllerBase(
            ITempFileCacheManager tempFileCacheManager,
            IBinaryObjectManager binaryObjectManager,
            IMimeTypeMap mimeTypeMap,
            IHttpContextAccessor httpContextAccessor,
            FileUploadHelper fileUploadHelper,
            IAppFolder appFolder
        )
        {
            _tempFileCacheManager = tempFileCacheManager;
            _binaryObjectManager = binaryObjectManager;
            _mimeTypeMap = mimeTypeMap;
            _httpContextAccessor = httpContextAccessor;
            _fileUploadHelper = fileUploadHelper;
            _appFolder = appFolder;
        }


        [AbpAuthorize(AppPermissions.Pages_Files_Download)]
        [HttpGet]
        [DisableAuditing]
        public ActionResult DownloadCommonFileByName(string fileName)
        {
            return File(new FileStream(Path.Combine(_appFolder.CommonFiesFolder, fileName), FileMode.Open),
                _mimeTypeMap.GetMimeType(fileName), fileName);
        }
        [AbpAuthorize(AppPermissions.Pages_Files_Download)]
        [HttpGet]
        [DisableAuditing]
        public ActionResult DownloadBigFileByName(string fileName)
        {
            return File(new FileStream(Path.Combine(_appFolder.BigFilesFolder, fileName), FileMode.Open),
                _mimeTypeMap.GetMimeType(fileName), fileName);
        }
        [AbpAuthorize(AppPermissions.Pages_Files_Download)]
        [HttpGet]
        [DisableAuditing]
        public ActionResult DownloadTempFile(FileDto file)
        {
            var bytes = _tempFileCacheManager.GetFile(file.FileToken);
            if (bytes == null)
            {
                return NotFound("未发现请求的文件");
            }

            return File(bytes, file.FileType, file.FileName);
        }
        [AbpAuthorize(AppPermissions.Pages_Files_Download)]
        [HttpGet]
        [DisableAuditing]
        public async Task<ActionResult> DownloadBinaryFile(Guid id, string contentType, string fileName)
        {
            var fileObject = await _binaryObjectManager.GetOrNullAsync(id);
            if (fileObject == null)
            {
                return StatusCode((int)HttpStatusCode.NotFound);
            }

            if (fileName.IsNullOrEmpty())
            {
                if (!fileObject.Description.IsNullOrEmpty() &&
                    !Path.GetExtension(fileObject.Description).IsNullOrEmpty())
                {
                    fileName = fileObject.Description;
                }
                else
                {
                    return StatusCode((int)HttpStatusCode.BadRequest);
                }
            }

            if (contentType.IsNullOrEmpty())
            {
                if (!Path.GetExtension(fileName).IsNullOrEmpty())
                {
                    contentType = _mimeTypeMap.GetMimeType(fileName);
                }
                else
                {
                    return StatusCode((int)HttpStatusCode.BadRequest);
                }
            }

            return File(fileObject.Bytes, contentType, fileName);
        }
        [AbpAuthorize(AppPermissions.Pages_Files_Upload)]
        [HttpPut]

        [DisableAuditing]
        public async Task<ActionResult> CommonFileUpload()
        {
            var results = new List<UploadFileResult>();
            var file = Request.Form.Files.First();
            if (file == null)
            {
                throw new UserFriendlyException("文件未发现");
            }

            if (file.Length > MaxCommonFileSize)
            {
                throw new UserFriendlyException("文件超出 10M 大小的限制");
            }

            byte[] bytes;
            using (var stream = file.OpenReadStream())
            {
                bytes = stream.GetAllBytes();
            }


            var savedName = Guid.NewGuid().ToString();

            await System.IO.File.WriteAllBytesAsync(
                Path.Combine(_appFolder.CommonFiesFolder, savedName + Path.GetExtension(file.FileName)),
                bytes);
            results.Add(new UploadFileResult
            {
                OriginalFileName = file.FileName,
                SavedFileName = savedName + Path.GetExtension(file.FileName),
                FileSize = bytes.Length,
                ContentType = file.ContentType
            });

            return Json(results);
        }
        [AbpAuthorize(AppPermissions.Pages_Files_Upload)]
        [HttpPut]
        [DisableAuditing]
        public async Task<ActionResult> BigFileUpload()
        {
            var results = new List<UploadFileResult>();
            var context = _httpContextAccessor.HttpContext;
            await _fileUploadHelper.UploadPartialFile(context, results, SaveType.A);
            return Json(results);
        }
    }
}